package singleThreaded;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.text.DecimalFormat;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

/**
 * Reporter takes care of reporting the expected info to the user.
 * @author Son Pham
 * @version 1.0
 */
public class Reporter
{
  /**
   * The entry set of <keyword, hit>.
   */
  private Set<Entry<String, Integer>> my_entry_set;
  
  /**
   * The number of pages.
   */
  public int my_num_of_pages;
  
  /**
   * The number of words.
   */
  private int my_num_of_words;
  
  /**
   * The current link.
   */
  private String my_link;
  
  /**
   * The limit of number of pages.
   */
  private int my_limit;
  
  /**
   * The time elapsed.
   */
  public double my_time;
  
  /**
   * The number of links which have been found so far.
   */
  private int my_num_of_links;
  
  /**
   * the txt file to report
   */
  File my_text_report = null;
  
  /**
   * Format for 2 decimal places.
   */
  public final DecimalFormat my_df_2 = new DecimalFormat("#.##");
  
  /**
   * Format for 3 decimal places.
   */
  public final DecimalFormat my_df_3 = new DecimalFormat("#.###");
  
  /**
   * Construct a Reporter object.
   * @param the_entry_set The entry set.
   * @param the_num_of_pages The number of pages.
   * @param the_num_of_words The number of words.
   */
  public Reporter (final Set<Entry<String, Integer>> the_entry_set,
                   final int the_num_of_pages,
                   final int the_num_of_words,
                   final int the_num_of_links,
                   final String the_link,
                   final int the_limit,
                   final double the_time_elapsed)
  {
    my_entry_set = the_entry_set;
    my_num_of_pages = the_num_of_pages;
    my_num_of_words = the_num_of_words;
    my_num_of_links = the_num_of_links;
    my_link = the_link;
    my_limit = the_limit;
    my_time = the_time_elapsed;

  }
  
  public Reporter()
  {
    my_entry_set = null;
    my_num_of_pages = 0;
    my_num_of_words = 0;
    my_num_of_links = 0;
    my_link = "";
    my_limit = 0;
    my_time = 0;
  }
  
  /**
   * 
   * @return The whole report.
   */
  public String report()
  {
    final StringBuffer report = new StringBuffer(200);
    report.append("Parsed: " + my_link + "\n");
    report.append("Pages Retrieved: " + my_num_of_pages + "\n");
    report.append("Average words per page: " + my_num_of_words / my_num_of_pages + "\n");
    report.append("Average URLs per page: " + my_num_of_links / my_num_of_pages + "\n");
    report.append(reportKeywordAndHit());
    report.append("\n\n");
    report.append("Page litmit: " + my_limit + "\n");
    report.append("Average parse time per page: " + 
                  my_df_3.format(my_time / my_num_of_pages) + " miliseconds\n");
    report.append("Total running time: " + my_df_2.format(my_time) + " miliseconds\n");
    return report.toString();
  }
  
  /**
   * 
   * @return The string report of keywords and hits.
   */
  public String reportKeywordAndHit()
  {
    StringBuffer result = new StringBuffer();
    double ave_hit;

    
    String the_head_string = String.format("%-25s%s\t%s", "Keyword", "Ave. hits per page", "Total hits");
    result.append(the_head_string + "\n");
    for (Map.Entry<String, Integer> entry : my_entry_set)
    {

      ave_hit = (double) entry.getValue() / my_num_of_pages;
      String the_string = String.format("%-25s%.2f\t\t\t%d",entry.getKey(), ave_hit, entry.getValue());
      result.append(the_string + "\n");
    }
    return result.toString();
  }
  
  /**
   * 
   * @return The final report.
   */
  public String finalReport()
  {
    StringBuffer report = new StringBuffer(200);
    report.append("Final statistic:\n");
    report.append("Total pages Retrieved: " + my_num_of_pages + "\n");
    report.append("Average words per page: " + my_num_of_words / my_num_of_pages + "\n");
    report.append("Average URLs per page: " + my_num_of_links / my_num_of_pages + "\n");
    report.append(reportKeywordAndHit());
    report.append("Page litmit: " + my_limit + "\n");
    report.append("Average parse time per page: " + 
                  my_df_3.format(my_time / my_num_of_pages) + " miliseconds\n");
    report.append("Total running time: " + my_df_2.format(my_time) + " miliseconds\n");
    return report.toString();
  }
  
  /**
   * Write out the report for single thread.
   */
  public void singleThreadTextReport()
  {
    try{
    // Create file 
      FileWriter ST = new FileWriter("spiderRunST.txt", true);

      BufferedWriter out = new BufferedWriter(ST);
      out.append("Average parse time per page: " + 
                    my_df_3.format(my_time / my_num_of_pages) + " ");
      out.newLine();
      out.append("Total running time: " + my_df_2.format(my_time) + "\n");
      out.newLine();
      out.close();
    //Close the output stream
    
    }catch (Exception e){//Catch exception if any
      System.err.println("Error: " + e.getMessage());
    }
  }
  
  /**
   * Write out the report for multi thread.
   */
  public void MultiThreadTextReport()
  {
    try{
    // Create file 
      FileWriter ST = new FileWriter("spiderRunMT.txt", true);

      BufferedWriter out = new BufferedWriter(ST);
      out.append("Average parse time per page: " + 
                    my_df_3.format(my_time / my_num_of_pages) + " ");
      out.newLine();
      out.append("Total running time: " + my_df_2.format(my_time) + "\n");
      out.newLine();
      out.close();
    //Close the output stream
    
    }catch (Exception e){//Catch exception if any
      System.err.println("Error: " + e.getMessage());
    }    
  }
}
